package info.javafans.cdn.web.servlet;

import info.javafans.cdn.struct.ActionMapping;
import info.javafans.cdn.struct.StructConfig;
import info.javafans.cdn.web.action.Action;
import info.javafans.cdn.web.action.LoginAction;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections.map.LRUMap;
import org.apache.log4j.Logger;

/**
 * Servlet implementation class ControllerServlet
 */
public class ActionServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private static Logger logger = Logger.getLogger(ActionServlet.class);
	// Action缓存
	private static final LRUMap SERVICE_CACHE = new LRUMap(10);
	// Action配置信息
	private static StructConfig structConfig = null;
	
	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public ActionServlet() {
		super();
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
			IOException {
		//创建配置信息
		if (structConfig == null) {
			String realPath = this.getServletContext().getRealPath("/");
			structConfig = new StructConfig(realPath);
		}
		//获取请求的URI
		String actionPath = this.parseUrl(request.getRequestURI());
//		logger.debug("actionPath:"+actionPath);
		Action action = this.findAction(actionPath);
		
		try {
			String forwardName = action.execute(request, response);
			ActionMapping actionMapping = action.getActionMapping();
			String forward = actionMapping.getForward(forwardName);
//			logger.debug("forward:"+forward);
			request.getRequestDispatcher(forward).forward(request, response);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 截取URI
	 * 
	 * @param requestURI
	 * @return
	 */
	protected String parseUrl(String requestURI) {
		int indexStart = requestURI.lastIndexOf('/');
		int indexEnd = requestURI.indexOf(".do");
		if (indexEnd == -1) {
			// //访问的URI不合法
			return null;
		}
		String actionPath = requestURI.substring(indexStart + 1, indexEnd);

		return "/" + actionPath;
	}
	
	/**
	 * 获得Action
	 * @param path
	 * @return
	 */
	protected Action findAction(String path) {
		Object o = SERVICE_CACHE.get(path);
		Action action = null;
		if (o == null) {
//			logger.debug("Cache is null");
			ActionMapping actionMapping = structConfig.getActionMapping(path);
			if (actionMapping == null) {
//				logger.error("actionMapping is null");
				return null;
			}
			String className = actionMapping.getType();
			Class<?> actionClass;
			try {
				logger.debug("className:"+className);
				actionClass = Class.forName(className);
				action = (Action)actionClass.newInstance();
				action.setActionMapping(actionMapping);
				SERVICE_CACHE.put("path", action);
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		else {
//			logger.debug("Cache is not null");
			action = (Action)o;
		}
		
		return action;
	}
}
